﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.Serialization.Formatters.Binary;
using PetkaWebDav.Server.Framework.BaseClasses;
using PetkaWebDav.Server.Framework.Classes;
using Microsoft.WindowsAzure.Storage.Blob;
using System.IO;
using PetkaWebDav.Server.Framework.Enums;
using System.Web;

namespace CloudStorageLight.Core.WebDav.Handlers
{
    /// <summary>
    /// Custom implementation example for DavLock.
    /// </summary>
    public sealed class DavLock : DavLockBase
    {
        public DavLock()
        {
        }

        protected override async Task OnProcessDavRequest(EventArgs e)
        {

            //Check to see if the original resource exists
            BlobItem _fileInfo = await RequestWrapper.DownloadBlobAttributes(this.GetRelativeRequestPath());
            if (_fileInfo == null)
                base.AbortRequest(ServerResponseCode.NotFound);
            else
            {
                ////Check to see if a lock already exists
                //CloudBlockBlob lockFile = RequestWrapper.GetLockFileByFileName(_fileInfo.Name);

                //if (lockFile != null && lockFile.Exists())
                //{
                //    using (MemoryStream _lockFileStream = new MemoryStream())
                //    {
                //        BinaryFormatter _binaryFormatter = new BinaryFormatter();
                //        lockFile.DownloadToStream(_lockFileStream);
                //        _lockFileStream.Position = 0;
                //        var lockInfo = (DavLockProperty)_binaryFormatter.Deserialize(_lockFileStream);
                //        if (!lockInfo.GetLockTokens().Any(x=> this.RequestLock.GetLockTokens().Contains(x))) base.AbortRequest(DavLockResponseCode.Locked);
                //    }
                //}
                if (_fileInfo.Metadata.ContainsKey("OpaqueLock") && _fileInfo.Metadata["OpaqueLock"] != null)
                {
                    var token = (string)_fileInfo.Metadata["OpaqueLock"];
                    if (!this.RequestLock.GetLockTokens().Contains(token))
                    {
                        base.AbortRequest(DavLockResponseCode.Locked);
                    }
                }
                else
                {
                    string _opaqueLock = System.Guid.NewGuid().ToString("D");

                    //Apply the requested lock information
                    base.ResponseLock.AddLockToken(_opaqueLock);

                    //Create the *.locked file
                    //RequestWrapper.GetLockInfo(_fileInfo.Name)


                    //string _lockedFilePath = _fileInfo.Name + "." + _opaqueLock + ".locked";

                    //using (MemoryStream _lockFileStream = new MemoryStream())
                    //{
                    //    BinaryFormatter _binaryFormatter = new BinaryFormatter();
                    //    _binaryFormatter.Serialize(_lockFileStream, base.ResponseLock);
                    //    _lockFileStream.Position = 0;
                    //    RequestWrapper.UploadBlob(_lockedFilePath, _lockFileStream);
                    //}
                    var user = GetUserName();
                    if (user == null)
                    {
                        base.AbortRequest(ServerResponseCode.Unauthorized);
                    }
                    else
                    {
                        int timeout = 60 * 60;

                        foreach(string itemKey in System.Web.HttpContext.Current.Request.Headers.Keys)
                        {
                            if (itemKey == "Timeout")
                            {
                                var keyValue = System.Web.HttpContext.Current.Request.Headers["Timeout"];
                                if (keyValue.StartsWith("Second-"))
                                {
                                    timeout = int.Parse(keyValue.Replace("Second-", ""));
                                }
                            }
                        }
                        await RequestWrapper.CheckoutBlob(_fileInfo.Path, timeout, this.RequestLock.LockOwner, _opaqueLock);
                    }

                }
            }
        }

        private string GetUserName()
        {
            if (!System.Web.HttpContext.Current.User.Identity.IsAuthenticated) return null;
            return System.Web.HttpContext.Current.User.Identity.Name;
        }


        protected async override Task OnRefreshLockDavRequest(DavRefreshEventArgs e)
        {
            //Check to see if the lock exists
            //CloudBlockBlob _lockFile = RequestWrapper.GetLockFileByLockToken(e.LockToken);

            //if (_lockFiles.Length == 0)
            //if (_lockFile == null)
            //    base.AbortRequest(DavLockResponseCode.PreconditionFailed);

            var blob = (BlobFile)await RequestWrapper.GetRequestFile();

            if (blob == null || !blob.Metadata.ContainsKey("OpaqueLock") || blob.OpaqueLock == null)
            {
                base.AbortRequest(DavLockResponseCode.PreconditionFailed);
            }
            else
            {
                //Deserialize the lock information
                DavLockProperty _lockProperty = null;

                _lockProperty = new DavLockProperty();
                _lockProperty.AddLockToken(blob.OpaqueLock);
                //using (MemoryStream _lockFileStream = new MemoryStream())
                //{
                //    BinaryFormatter _binaryFormatter = new BinaryFormatter();
                //    _lockFile.DownloadToStream(_lockFileStream);
                //    _lockFileStream.Position = 0;
                //    _lockProperty = (DavLockProperty)_binaryFormatter.Deserialize(_lockFileStream);
                //}

                base.ResponseLock = _lockProperty;

                //Set the requested lockTimeout or overwrite
                base.ResponseLock.LockTimeout = 10;
            }
        }
    }
}
